//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Logging Application Block
//===============================================================================
//  LogParser - Log File Parser
//  Copyright (C) 2007  Alois Kraus
//  
//  This source code is published under the Microsoft Permissive License (Ms-PL)
//  http://www.microsoft.com/resources/sharedsource/licensingbasics/permissivelicense.mspx
//===============================================================================

using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Globalization;
using System.Collections.Generic;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging;

namespace EntLibContrib.Logging.Parser
{
	/// <summary>
	/// It is a tokenizer but it could also be called LogEntry Deserializer. It does
	/// try to "deserialize" form a given text fragment LogEntry objects using regular
	/// expressions.
	/// </summary>
	public class Tokenizer : LogEntryParser
	{
		#region Fields
		Dictionary<string, List<Regex>> myFileRegularExpressions;
		#endregion

		#region Construction
		/// <summary>
		/// Initializes a new instance of the <see cref="Tokenizer"/> class.
		/// </summary>
		/// <param name="builder">The builder.</param>
		public Tokenizer(RegularExpressionBuilder builder)
		{
			Init(builder);
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="Tokenizer"/> class.
		/// </summary>
		/// <param name="builder">The builder.</param>
		/// <param name="theTimeStampParser">The time stamp parser to use</param>
		public Tokenizer(RegularExpressionBuilder builder, ITimeStampParser theTimeStampParser)
			: base(theTimeStampParser)
		{
			Init(builder);
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Gets the parsed entries.
		/// </summary>
		/// <param name="messageText">The message text.</param>
		/// <param name="fileName">Name of the file.</param>
		/// <returns></returns>
		public IEnumerable<LogEntry> GetDeserializedLogEntries(string messageText, string fileName)
		{
			if (messageText == null)
				throw new ArgumentNullException(messageText);

			// get regular expressions for configure file name
			List<Regex> rexList = myFileRegularExpressions[Path.GetFileName(fileName)];


			bool bMatch = false;
			foreach (Regex rex in rexList)
			{
				foreach (Match m in rex.Matches(messageText))
				{
					bMatch = true;
					yield return DeserializeLogEntry(m);
				}
			}

			if (!bMatch)
			{
				// if the message could not be parsed we return it as whole.
				LogEntry unparsedEntry = new LogEntry();
				unparsedEntry.Severity = TraceEventType.Information;
				unparsedEntry.TimeStamp = DateTime.MinValue;
				unparsedEntry.Message = messageText;

				yield return unparsedEntry;
			}
		}
		#endregion

		#region Private Methods
		private void Init(RegularExpressionBuilder builder)
		{
			if (builder == null)
				throw new ArgumentNullException("builder");

			myFileRegularExpressions = builder.FileRegularExpressions;
		}
		#endregion
	}
}
